package filesystem.server.file;

import java.util.LinkedList;


/**
 * Classe que gerencia os arquivos.
 * 
 * Ao criar um arquivo esta classe verifica se ele já existe, caso não exista,
 * é criado um objeto que fará o controle de acesso ao arquivo.
 * 
 * Ao deletar um arquivo esta classe verifica se ele realmente existe, caso
 * exista, é verificado se o arquivo já está sendo acessado, em caso contrário,
 * o arquivo é removido.
 * 
 * Ao acessar um arquivo é devolvido, caso ele exista, o objeto responsável pelo
 * controle do próprio arquivo. 
 *
 */
public class FileFactory {
	private static LinkedList<FileHandler> files = new LinkedList<FileHandler>();
	
	/**
	 * Cria um arquivo e armazena o objeto de controle de acesso.
	 * 
	 * @param name Nome do arquivo no sistema.
	 * @param hash o hash do arquivo.
	 * @param path o caminho do arquivo no nó.
	 * @param host o nó em que está localizado o arquivo.
	 * @return true no sucesso da operação, false, caso contrário.
	 */
	public static boolean createFile(String name, String path, String host){
		for(FileHandler handler: files){
			if(handler.getName().equals(name)){
				return false;
			}
		}
		synchronized (files) {
			files.add(new FileHandler(name, path, host));
		}
		return true;
	}
	
	/**
	 * Obtém o objeto de controle de acesso do arquivo
	 * 
	 * @param name Nome do arquivo
	 * @return O objeto de controle ou null caso o objeto não exista
	 */
	public static FileHandler getFile(String name){
		for(FileHandler handler: files){
			if(handler.getName().equals(name)){
				return handler;
			}
		}
		return null;
	}
	
	/**
	 * Deleta o objeto de controle do arquivo, o tornando inacessível.
	 * 
	 * @param name Nome do arquivo.
	 * @return true no sucesso da operação, false, caso contrário.
	 */
	public static boolean deleteFile(String name){
		for(int i = 0; i < files.size(); i++){
			FileHandler handler = files.get(i);
			if(handler.getName().equals(name)){
				if(handler.writeRequest()){
					synchronized (files){
						files.remove(i);
					}
				}else{
					return false;
				}
			}
		}
		return true;
	}
}
